//****************************************************************
// Autor:   Yimy Juarez 
//          
//       
// Seccion: 10
// Nombre del Archivo: SinglyLinkedList.java
// Fecha de Modificacion:20/09/2012
// Descripcion:
// Clase de implementación de la lista simple
// ***************************************************************
package hoja.de.trabajo.pkg6;

import java.util.Iterator;


public class SinglyLinkedList<E> extends abstractList<E>
{

   protected int count; // list size
   protected Node<E> head; // ref. to first element

   public SinglyLinkedList()
   // post: generates an empty list
   {
      head = null;
      count = 0;
   }
   
   public int size()
   // post: returns number of elements in list
  {
        return count;
  }
  
  public void addFirst(E value)
  // post: value is added to beginning of list
  {
     // note order that things happen:
     // head is parameter, then assigned
     head = new Node<E>(value, head);
     count++;
  }
   
   public void clear()
   // post: empties list
   {
   }

   public void addLast(E value)
   // post: value is added to end of list
   {
       Node<E> temp = new Node<E>(value,null);
        if(head != null) {
            Node<E> temp2 = head;
            while (temp2.next() != null) {
                temp2 = temp2.next();
            }
            temp2.setNext(temp);
        } else head = temp;
        count++;
   }

   public E getFirst()
   // pre: list is not empty
   // post: returns first value in list
   {
       return head.value();
   }        
   
   public E getLast()
   // pre: list is not empty
   // post: returns last value in list
   {
       return null;
   }
           
   public E removeFirst()
   // pre: list is not empty
   // post: removes first value from list
   {
       return null;
   }
           
   public E removeLast()
   // pre: list is not empty
   // post: removes last value from list
   {
        Node<E> finger = head;
        Node<E> previous = null;
        while (finger.next() != null) // find end of list
        {
        previous = finger;
        finger = finger.next();
        }
        // finger is null, or points to end of list
        if (previous == null)
        {
        // has exactly one element
        head = null;
        }
        else
        {
        // pointer to last element is reset
        previous.setNext(null);
        }
        count--;
        return finger.value();
   }

   public E remove(E value)
   // post: removes and returns element equal to value
   // otherwise returns null
   {
        Node<E> temp = head;
        Node<E> previous = null;
        while (temp != null && !temp.value().equals(value)) {
            previous = temp;
            temp = temp.next();
        }
        if (temp != null) {
            if (previous == null) {
                head = temp.next();
            } else  {
                previous.setNext(temp.next());
            } 
            count--;
            return temp.value();
        }
        return null;
   }

   public void add(E value)
   // post: value is added to tail of list
   {
       
   }

   public E remove()
   // pre: list has at least one element
   // post: removes last value found in list
   {
       return null;
   }

   public E get()
   // pre: list has at least one element
   // post: returns last value found in list
   {
       return null;
   }
 

   public int indexOf(E value)
   // pre: value is not null
   // post: returns (0-origin) index of value,
   // or -1 if value is not found
   {
       return 0;
   }

   public int lastIndexOf(E value)
   // pre: value is not null
   // post: returns (0-origin) index of value,
   // or -1 if value is not found
   {
       return 0;
   }

   public E get(int i)
   // pre: 0 <= i < size()
   // post: returns object found at that location
   {
       return null;
   }

   public E set(int i, E o)
   // pre: 0 <= i < size()
   // post: sets ith entry of list to value o;
   // returns old value
   {
       return null;
   }
           
   public void add(int i, E o)
   // pre: 0 <= i <= size()
   // post: adds ith entry of list to value o
   {
   }

   public E remove(int i)
   // pre: 0 <= i < size()
   // post: removes and returns object found at that location
   {
       return null;
   }

   public Iterator<E> iterator()
   // post: returns an iterator allowing
   // ordered traversal of elements in list
   {
        return new SiglyLinkedListIterator();
   }

    /**
             * Clase que permite la implementación de un iterador de la lista
             */
            private class SiglyLinkedListIterator implements Iterator<E> {
                
               // Ya que la clase es interna esta puede utilizar
                // los atributos de la clase anterior
                
                protected Node<E> current;

                
                
                
                
                /**
                 * Constructor de la clase SinglyLinkedListIterator
                 */
                public SiglyLinkedListIterator() {
                    current = head;
                }

                
                /**
                 * Método que permite reiniciar la referencia del iterador de 
                 * la lista. 
                 */
                public void reset() {
                    current = head;
                }

                
                /**
                 * Método que indica si aun hay una nueva objeto
                 * a analizar
                 * @return true si existe un objeto
                 */
                public boolean hasNext() {
                    return current != null;
                }

                /**
                 * Método que retorna el valor actual e incrementa al Iterator.
                 * @return valor E actual
                 */
                public E next() {
                    E temp = current.value();
                    current = current.next();
                    return temp;
                }

                public void remove() {}
            }    
    
}


